package com.tupi.project.view.refresh;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Matrix;
import android.graphics.drawable.AnimationDrawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.tupi.project.R;

import java.text.SimpleDateFormat;
import java.util.Date;

import butterknife.BindView;
import butterknife.ButterKnife;
import in.srain.cube.views.ptr.PtrFrameLayout;
import in.srain.cube.views.ptr.PtrUIHandler;
import in.srain.cube.views.ptr.indicator.PtrIndicator;

/**
 * author zhetengxiang
 * Date 2016/7/27
 * step0:下拉/准备下拉状态
 * step1:下拉->可刷新状态
 * step2:刷新状态
 * step3:刷新结束状态
 * step4:可刷新->下拉状态
 */

public class RefreshHeader extends LinearLayout implements PtrUIHandler
{
    private static final String TAG = RefreshHeader.class.getSimpleName();
    @BindView(R.id.ivFirst)
    ImageView ivFirst;
    @BindView(R.id.ivSecond)
    ImageView ivSecond;
    @BindView(R.id.ivThird)
    ImageView ivThird;
    @BindView(R.id.tvMsg)
    TextView tvMsg;
    private Matrix mMatrix = new Matrix();
    private AnimationDrawable mSecondAnimation;
    private AnimationDrawable mThirdAnimation;
    
    /**
     * 以下为更新时间相关代码
     */
    private String mLastUpdateTimeKey;
    private static SimpleDateFormat sDataFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private final static String KEY_SharedPreferences = "cube_ptr_classic_last_update";
    private LastUpdateTimeUpdater mLastUpdateTimeUpdater = new LastUpdateTimeUpdater();
    private long mLastUpdateTime = -1;
    private boolean mShouldShowLastUpdate;
    @BindView(R.id.update_time)
    TextView mLastUpdateTextView;
    
    public RefreshHeader(Context context)
    {
        this(context, null);
    }
    
    public RefreshHeader(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
    }
    
    public RefreshHeader(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
        View headerView = LayoutInflater.from(context).inflate(R.layout.header_meituan, this);
        ButterKnife.bind(headerView);
        init();
    }
    
    private void init()
    {
        mSecondAnimation = (AnimationDrawable) ivSecond.getDrawable();
        mThirdAnimation = (AnimationDrawable) ivThird.getDrawable();
    }
    
    @Override
    public void onUIReset(PtrFrameLayout frame)
    {
        resetView();
        mShouldShowLastUpdate = true;
    }
    
    @Override
    public void onUIRefreshPrepare(PtrFrameLayout frame)
    {
        mShouldShowLastUpdate = true;
        pullStep0(0.0f);
        mLastUpdateTimeUpdater.start();
    }
    
    @Override
    public void onUIRefreshBegin(PtrFrameLayout frame)
    {
        mShouldShowLastUpdate = false;
        pullStep2();
        mLastUpdateTimeUpdater.stop();
    }
    
    @Override
    public void onUIRefreshComplete(PtrFrameLayout frame)
    {
        pullStep3();
        
        // update last update time
        SharedPreferences sharedPreferences = getContext().getSharedPreferences
                (KEY_SharedPreferences, 0);
        if (!TextUtils.isEmpty(mLastUpdateTimeKey))
        {
            mLastUpdateTime = new Date().getTime();
            sharedPreferences.edit().putLong(mLastUpdateTimeKey, mLastUpdateTime).commit();
        }
    }
    
    /**
     * 下拉的时候
     * 07-28 10:25:16.810 31949-31949/harry.com.pullrefresh I/PtrMeiTuanHeader: mOffsetToRefresh
     * =176,currentPos
     * =303,lastPos =302
     * 07-28 10:25:16.820 31949-31949/harry.com.pullrefresh I/PtrMeiTuanHeader: mOffsetToRefresh
     * =176,currentPos
     * =304,lastPos =303
     * 07-28 10:25:16.840 31949-31949/harry.com.pullrefresh I/PtrMeiTuanHeader: mOffsetToRefresh
     * =176,currentPos
     * =305,lastPos =304
     * 07-28 10:25:16.870 31949-31949/harry.com.pullrefresh I/PtrMeiTuanHeader: mOffsetToRefresh
     * =176,currentPos
     * =306,lastPos =305
     */
    @Override
    public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status,
                                   PtrIndicator ptrIndicator)
    {
        final int mOffsetToRefresh = frame.getOffsetToRefresh();
        final int currentPos = ptrIndicator.getCurrentPosY();
        final int lastPos = ptrIndicator.getLastPosY();
        if (lastPos < mOffsetToRefresh)
        {
            if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE)
            {
                float scale = lastPos / Float.valueOf(mOffsetToRefresh);
                pullStep0(scale);
            }
        }
        Log.i(TAG, "mOffsetToRefresh =" + mOffsetToRefresh + ",currentPos =" + currentPos + "," +
                "lastPos =" + lastPos);
        if (currentPos < mOffsetToRefresh && lastPos >= mOffsetToRefresh)
        {
            if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE)
            {
                pullStep4();
            }
        } else if (currentPos > mOffsetToRefresh && lastPos <= mOffsetToRefresh)
        {
            if (isUnderTouch && status == PtrFrameLayout.PTR_STATUS_PREPARE)
            {
                pullStep1(frame);
            }
        }
    }
    
    private void pullStep0(float scale)
    {
        ivFirst.setVisibility(View.VISIBLE);
        ivSecond.setVisibility(View.INVISIBLE);
        ivThird.setVisibility(View.INVISIBLE);
        scaleImage(scale);
        tvMsg.setText(getResources().getString(R.string.cube_ptr_pull_down_to_refresh));
    }
    
    private void pullStep1(PtrFrameLayout frame)
    {
        if (!frame.isPullToRefresh())
        {
            ivFirst.setVisibility(View.INVISIBLE);
            ivSecond.setVisibility(View.VISIBLE);
            ivThird.setVisibility(View.INVISIBLE);
            mSecondAnimation.start();
            tvMsg.setText(getResources().getString(R.string.cube_ptr_release_to_refresh));
        }
    }
    
    private void pullStep2()
    {
        ivFirst.setVisibility(View.INVISIBLE);
        ivSecond.setVisibility(View.INVISIBLE);
        ivThird.setVisibility(View.VISIBLE);
        cancelAnimationSecond();
        mThirdAnimation.start();
        tvMsg.setText(R.string.cube_ptr_refreshing);
    }
    
    private void pullStep3()
    {
        ivFirst.setVisibility(View.INVISIBLE);
        ivSecond.setVisibility(View.INVISIBLE);
        ivThird.setVisibility(View.VISIBLE);
        cancelAnimationThird();
        tvMsg.setText(getResources().getString(R.string.cube_ptr_refresh_complete));
    }
    
    /**
     * 可刷新到不可刷新
     */
    private void pullStep4()
    {
        ivFirst.setVisibility(View.VISIBLE);
        ivSecond.setVisibility(View.INVISIBLE);
        ivThird.setVisibility(View.INVISIBLE);
        tvMsg.setText(getResources().getString(R.string.cube_ptr_pull_down_to_refresh));
    }
    
    private void scaleImage(float scale)
    {
        mMatrix.setScale(scale, scale, ivFirst.getWidth() / 2, ivFirst.getHeight() / 2);
        ivFirst.setImageMatrix(mMatrix);
    }
    
    @Override
    protected void onDetachedFromWindow()
    {
        super.onDetachedFromWindow();
        resetView();
        if (mLastUpdateTimeUpdater != null)
        {
            mLastUpdateTimeUpdater.stop();
        }
    }
    
    private void resetView()
    {
        cancelAnimations();
    }
    
    private void cancelAnimations()
    {
        cancelAnimationSecond();
        cancelAnimationThird();
    }
    
    private void cancelAnimationSecond()
    {
        if (mSecondAnimation != null && mSecondAnimation.isRunning())
        {
            mSecondAnimation.stop();
        }
    }
    
    private void cancelAnimationThird()
    {
        if (mThirdAnimation != null && mThirdAnimation.isRunning())
        {
            mThirdAnimation.stop();
        }
    }
    
    
    /**
     * Specify the last update time by this key string
     *
     * @param key
     */
    public void setLastUpdateTimeKey(String key)
    {
        if (TextUtils.isEmpty(key))
        {
            return;
        }
        mLastUpdateTimeKey = key;
    }
    
    /**
     * Using an object to specify the last update time.
     *
     * @param object
     */
    public void setLastUpdateTimeRelateObject(Object object)
    {
        setLastUpdateTimeKey(object.getClass().getName());
    }
    
    private void tryUpdateLastUpdateTime()
    {
        if (TextUtils.isEmpty(mLastUpdateTimeKey) || !mShouldShowLastUpdate)
        {
            mLastUpdateTextView.setVisibility(GONE);
        } else
        {
            String time = getLastUpdateTime();
            if (TextUtils.isEmpty(time))
            {
                mLastUpdateTextView.setVisibility(GONE);
            } else
            {
                mLastUpdateTextView.setVisibility(VISIBLE);
                mLastUpdateTextView.setText(time);
            }
        }
    }
    
    private String getLastUpdateTime()
    {
        
        if (mLastUpdateTime == -1 && !TextUtils.isEmpty(mLastUpdateTimeKey))
        {
            mLastUpdateTime = getContext().getSharedPreferences(KEY_SharedPreferences, 0).getLong
                    (mLastUpdateTimeKey, -1);
        }
        if (mLastUpdateTime == -1)
        {
            return null;
        }
        long diffTime = new Date().getTime() - mLastUpdateTime;
        int seconds = (int) (diffTime / 1000);
        if (diffTime < 0)
        {
            return null;
        }
        if (seconds <= 0)
        {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(getContext().getString(R.string.cube_ptr_last_update));
        
        if (seconds < 60)
        {
            sb.append(seconds + getContext().getString(R.string.cube_ptr_seconds_ago));
        } else
        {
            int minutes = (seconds / 60);
            if (minutes > 60)
            {
                int hours = minutes / 60;
                if (hours > 24)
                {
                    Date date = new Date(mLastUpdateTime);
                    sb.append(sDataFormat.format(date));
                } else
                {
                    sb.append(hours + getContext().getString(R.string.cube_ptr_hours_ago));
                }
                
            } else
            {
                sb.append(minutes + getContext().getString(R.string.cube_ptr_minutes_ago));
            }
        }
        return sb.toString();
    }
    
    private class LastUpdateTimeUpdater implements Runnable
    {
        
        private boolean mRunning = false;
        
        private void start()
        {
            if (TextUtils.isEmpty(mLastUpdateTimeKey))
            {
                return;
            }
            mRunning = true;
            run();
        }
        
        private void stop()
        {
            mRunning = false;
            removeCallbacks(this);
        }
        
        @Override
        public void run()
        {
            tryUpdateLastUpdateTime();
            if (mRunning)
            {
                postDelayed(this, 1000);
            }
        }
    }
}